package com.taobao.search.srevice.impl;

import com.alibaba.fastjson.JSON;
import com.taobao.base.model.RestResponse;
import com.taobao.base.utils.StringUtil;
import com.taobao.search.feignclient.HomeServiceClient;
import com.taobao.search.model.dto.GoodsDetailsDto;
import com.taobao.search.model.dto.GoodsPreviewDto1;
import com.taobao.search.model.dto.StoreDto;
import com.taobao.search.model.po.Goods;
import com.taobao.search.model.pojo.GoodsDoc;
import com.taobao.search.srevice.GoodsService;
import org.elasticsearch.action.DocWriteResponse;
import org.elasticsearch.action.delete.DeleteRequest;
import org.elasticsearch.action.delete.DeleteResponse;
import org.elasticsearch.action.get.GetRequest;
import org.elasticsearch.action.get.GetResponse;
import org.elasticsearch.action.index.IndexRequest;
import org.elasticsearch.action.index.IndexResponse;
import org.elasticsearch.action.search.SearchRequest;
import org.elasticsearch.action.search.SearchResponse;
import org.elasticsearch.action.update.UpdateRequest;
import org.elasticsearch.client.RequestOptions;
import org.elasticsearch.client.RestHighLevelClient;
import org.elasticsearch.index.query.QueryBuilders;
import org.elasticsearch.search.SearchHit;
import org.elasticsearch.search.SearchHits;
import org.elasticsearch.search.builder.SearchSourceBuilder;
import org.elasticsearch.xcontent.XContentType;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

@Service
public class GoodsServiceImpl implements GoodsService {

    @Autowired
    private RestHighLevelClient client;

    @Autowired
    private HomeServiceClient homeServiceClient;

    @Override
    public RestResponse<String> addDoc(Goods goods) {

        // 2.转换为GoodsDoc
        GoodsDoc goodsDoc = new GoodsDoc(goods);
        // 3.转JSON
        String json = JSON.toJSONString(goodsDoc);

        // 1.准备Request
        IndexRequest request = new IndexRequest("goods").id(goodsDoc.getGoodsId().toString());
        // 2.准备请求参数DSL，其实就是文档的JSON字符串
        request.source(json, XContentType.JSON);
        // 3.发送请求
        try {
            IndexResponse response = client.index(request, RequestOptions.DEFAULT);
            if(response.getResult() == DocWriteResponse.Result.CREATED){
                return RestResponse.success("添加文档成功");
            }else if(response.getResult() == DocWriteResponse.Result.UPDATED){
                return RestResponse.validfail("文档已存在");
            }else {
                return RestResponse.validfail("添加文档失败");
            }
        } catch (IOException e) {
            return RestResponse.validfail("添加文档失败");
        }
    }

        // 删除文档
    @Override
    public RestResponse<String> deleteDoc(Integer goodsId){
        // 1.准备Request      // DELETE /hotel/_doc/{id}
        DeleteRequest request = new DeleteRequest("goods", goodsId.toString());
        // 2.发送请求
        try {
            DeleteResponse delete = client.delete(request, RequestOptions.DEFAULT);
            if (delete.getResult() == DocWriteResponse.Result.DELETED) {
                return RestResponse.success("删除文档成功");
            }else{
                return RestResponse.validfail("文档不存在");
            }
        } catch (IOException e) {
            return  RestResponse.validfail("删除文档失败");

        }
    }


    @Override
    public RestResponse<Goods> searchDoc(String id) {
        // 1.准备Request      // GET /hotel/_doc/{id}
        GetRequest request = new GetRequest("goods", id);
        // 2.发送请求
        GetResponse response = null;
        try {
            response = client.get(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        // 3.解析响应结果
        String json = response.getSourceAsString();

        Goods goods = JSON.parseObject(json, Goods.class);
        System.out.println("goodsDoc = " + goods);

        return RestResponse.success(goods);
    }

    @Override
    public RestResponse<String> UpdateById(Goods goods) {
        // 1.准备Request
        UpdateRequest request = new UpdateRequest("goods", goods.getGoodsId().toString());
        // 2.准备参数
        request.doc(
                "title", goods.getTitle() // 例子
        );
        // 3.发送请求
        try {
            client.update(request, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        return RestResponse.success("更新成功");
    }

    @Override
    public RestResponse<List<GoodsDetailsDto>> goodsDetailsByTitle(String title) {
        List<Goods> goodsList = goodsAllByTitle(title).getResult();

        List<GoodsDetailsDto> goodsDetailsDtoList = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
            goodsDetailsDto.set_count(goods.get_count());
            goodsDetailsDto.setPrice(goods.getPrice());
            goodsDetailsDto.setTitle(goods.getTitle());
            goodsDetailsDto.setGoodsId(goods.getGoodsId());
            goodsDetailsDto.setVideoUrl(goods.getVideoUrl());
            goodsDetailsDto.setImgList(StringUtil.StringToList(goods.getImgList()));
            goodsDetailsDto.setRemark(goods.getRemark());
            goodsDetailsDto.setEvaluateId(goods.getEvaluateId());
            goodsDetailsDto.setDetailsId(goods.getDetailsId());
            goodsDetailsDto.setDetailsId(goods.getDetailsId());
            goodsDetailsDto.setStoreId(goods.getStoreId());
            goodsDetailsDtoList.add(goodsDetailsDto);
        }

        return RestResponse.success(goodsDetailsDtoList);
    }

    @Override
    public RestResponse<List<Goods>> goodsAllByTitle(String title) {
        // 创建查询请求
        SearchRequest searchRequest = new SearchRequest("goods");
        SearchSourceBuilder searchSourceBuilder = new SearchSourceBuilder();
        searchSourceBuilder.query(QueryBuilders.matchQuery("title", title));
        searchRequest.source(searchSourceBuilder);

        // 执行查询请求
        SearchResponse searchResponse = null;
        try {
            searchResponse = client.search(searchRequest, RequestOptions.DEFAULT);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }

        // 处理查询结果
        List<GoodsDoc> goodsDocList = handleResponse(searchResponse);

        List<Goods> goodsList = new ArrayList<>();
        for (GoodsDoc goodsDoc : goodsDocList) {
            Goods goods = new Goods();
            BeanUtils.copyProperties(goodsDoc, goods);
            goodsList.add(goods);
        }

        return RestResponse.success(goodsList);
    }

    @Override
    public RestResponse<List<GoodsPreviewDto1>> getGoodsPreviewByTitle(String title) {

        List<Goods> goodsList = goodsAllByTitle(title).getResult();

        List<GoodsPreviewDto1> goodsPreviewDto1List = new ArrayList<>();
        for (Goods goods : goodsList) {
            GoodsPreviewDto1 goodsPreviewDto1 = new GoodsPreviewDto1();
            StoreDto storeDto = homeServiceClient.getStoreById(goods.getStoreId()).getResult();

            goodsPreviewDto1.setStoreName(storeDto.getStoreName());
            goodsPreviewDto1.setStoreId(goods.getStoreId());
            goodsPreviewDto1.setGoodsId(goods.getGoodsId());
            goodsPreviewDto1.setImgUrl(goods.getImgUrl());
            goodsPreviewDto1.setPrice(goods.getPrice());
            goodsPreviewDto1.setTitle(goods.getTitle());
            goodsPreviewDto1.setLogistics(goods.getLogistics());
            goodsPreviewDto1.setFoodTag(goods.getFoodTag());
            BeanUtils.copyProperties(goods, goodsPreviewDto1);
            goodsPreviewDto1List.add(goodsPreviewDto1);
        }
        return RestResponse.success(goodsPreviewDto1List);
    }


    private GoodsDetailsDto convertToGoodsDetailsDto(GoodsDoc goodsDoc) {
        GoodsDetailsDto goodsDetailsDto = new GoodsDetailsDto();
        goodsDetailsDto.setGoodsId(goodsDoc.getGoodsId());
        goodsDetailsDto.setVideoUrl(goodsDoc.getVideoUrl());
        goodsDetailsDto.setImgList(StringUtil.StringToList(goodsDoc.getImgList()));
        goodsDetailsDto.setPrice(goodsDoc.getPrice());
        goodsDetailsDto.setRemark(goodsDoc.getRemark());
        goodsDetailsDto.setTitle(goodsDoc.getTitle());
        goodsDetailsDto.set_count(goodsDoc.get_count());
        goodsDetailsDto.setEvaluateId(goodsDoc.getEvaluateId());
        goodsDetailsDto.setDetailsId(goodsDoc.getDetailsId());
        goodsDetailsDto.setRecommendId(goodsDoc.getRecommendId());
        goodsDetailsDto.setStoreId(goodsDoc.getStoreId());
        return goodsDetailsDto;
    }

    private List<GoodsDoc> handleResponse(SearchResponse response) {
        SearchHits searchHits = response.getHits();
        // 4.1.总条数
        long total = searchHits.getTotalHits().value;
        System.out.println("总条数：" + total);
        // 4.2.获取文档数组
        SearchHit[] hits = searchHits.getHits();

        // 4.3
        List<GoodsDoc> goodsDocList = new ArrayList<>();
        // 4.4.遍历
        for (SearchHit hit : hits) {
            // 4.5.获取source
            String json = hit.getSourceAsString();
            // 4.6.反序列化，非高亮的
            GoodsDoc goodsDoc = JSON.parseObject(json, GoodsDoc.class);
            // 4.7
            goodsDocList.add(goodsDoc);
            // 4.8.打印
            System.out.println(goodsDoc);
        }

        return goodsDocList;
    }

}

